﻿using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Windows.Forms;
using Young3.FMSearch.Core.Converters;
using Young3.FMSearch.Core.Entities;
using Young3.FMSearch.Interface;
using Young3.FMSearch.Core.Entities.InGame;
using System.Diagnostics;
using Young3.FMSearch.Core.Managers;
using Young3.FMSearch.Core.Offsets;
using Young3.FMSearch.Utils;

namespace _Test
{
    public partial class Form1 : Form
    {
        FMContext fmRealtime = new FMContext(DatabaseModeEnum.Realtime);
        FMContext fmCached = new FMContext(DatabaseModeEnum.Cached);

        public Form1()
        {
            InitializeComponent();

            // callbacks that fire when loading is completed
            fmRealtime.GameLoaded += new Action(RealtimeLoaded);
            fmCached.GameLoaded += new Action(CacheLoaded);

            // when starting this app. We'll first start loading the realtime context
            new Action(()=>fmRealtime.LoadData()).BeginInvoke((s)=> { }, null);
        }

        void RealtimeLoaded()
        {
            // when realtime is loaded; start the cached loading, and set the program's title
            this.Invoke(new MethodInvoker(() => this.Text = string.Format("{0} - Hi {1} - Active screen: {2}", fmRealtime.MetaData.CurrentVersion, fmRealtime.HumanManagers.First().ToString(), fmRealtime.MetaData.ActiveObject == null ? "-" : fmRealtime.MetaData.ActiveObject.ToString())));
            
            new Action(() => fmCached.LoadData()).BeginInvoke((s) => { }, null);
        }

        void CacheLoaded()
        {
            // load the cache (ratings does cache itself, so just make sure we hit every player)
            Stopwatch sR = new Stopwatch(); sR.Start();
            var initRatings = (from p in fmCached.Players where p.Ratings().BestRating() > 0.99M select p).ToList();
            sR.Stop(); Debug.WriteLine("Calculate Rating: " + sR.ElapsedMilliseconds + " ms");

            this.Invoke(new MethodInvoker(() =>
                                              {
                                                  dataGridView1.AutoGenerateColumns = true;

                                                  Bind();
                                              }));
        }

        void Bind()
        {
            Stopwatch sw = new Stopwatch(); sw.Start();

            // this is a query
            // it's relatively easy, we query the cached context for players
            // whose name starts with the text in the textbox, with a rating of over 0.60
            // and with a nationality
            var players = (from p in fmCached.Players
                           let rating = p.Ratings().BestRating()
                           where
                           p.ToString().StartsWith(textBox1.Text)
                           && rating > 0.60M
                            && p.Nationality != null // for corrupt players
                           orderby rating descending
                           select new
                           {
                               Naam = p.ToString(),
                               Positie = p.PositionalSkills.ToString(),
                               Nationaliteit = p.Nationality.Name,
                               Club = p.Team != null && p.Team.Club != null ? p.Team.Club.Name : "",
                               Competitie = p.Team != null && p.Team.League != null ? p.Team.League.Name : "",
                               Value = string.Format("{0:c}", p.Value),
                               SaleValue = string.Format("{0:c}", p.SaleValue),
                               BestRating = string.Format("{0:F2}", p.Ratings().BestRating() * 100),
                           }).Take(100).ToList() 
                           // take(100) is best practice, so you dont have to show every player
                           // doing ToList() executes the query
                   ;
            sw.Stop();
            Debug.WriteLine("Player Rating query: " + sw.ElapsedMilliseconds + " ms");

            // NB. The above is not the fastest. For doing rating queries use rather
            // from p in Ratings.PlayerAddressesBetween(0.60M, 1.0M, fmCached.Players);

            dataGridView1.DataSource = players;
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            Bind();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }
    }

    class ClubDing
    {
        public string Name { get; set; }
        public decimal Rating { get; set; }
    }
}
